#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
测试用例执行器
从客户流失记录和ABC银行流失率数据中随机选择20个客户进行测试
使用优化后的main.py进行预测和干预分析
"""

import pandas as pd
import numpy as np
import random
import json
import sys
import os
from datetime import datetime
import warnings
warnings.filterwarnings('ignore')

# 添加项目路径
sys.path.append(r'c:\Users\ten\Desktop\ad-space-available-master\ad-space-available-master\ad-space-available\project\客户流失预测及干预mcp服务')

def load_and_sample_data():
    """
    加载数据并随机采样20个客户
    """
    print("正在加载客户数据...")
    
    # 加载两个数据文件
    file1 = r"c:\Users\ten\Desktop\ad-space-available-master\ad-space-available-master\ad-space-available\project\客户流失记录.csv"
    file2 = r"c:\Users\ten\Desktop\ad-space-available-master\ad-space-available-master\ad-space-available\project\ABC Multistate 银行流失率.csv"
    
    try:
        # 读取客户流失记录
        df1 = pd.read_csv(file1, encoding='utf-8')
        print(f"客户流失记录数据加载成功，共{len(df1)}条记录")
        
        # 读取ABC银行流失率数据
        df2 = pd.read_csv(file2, encoding='utf-8')
        print(f"ABC银行流失率数据加载成功，共{len(df2)}条记录")
        
        # 统一列名映射
        column_mapping = {
            '客户ID': 'customer_id',
            '信用评分': 'credit_score', 
            '信用分': 'credit_score',
            '地理位置': 'country',
            '国家': 'country',
            '性别': 'gender',
            '年龄': 'age',
            '任期': 'tenure',
            '余额': 'balance',
            '产品数量': 'products_number',
            '银行产品编号': 'products_number',
            '拥有收藏卡判定': 'has_credit_card',
            '信用卡': 'has_credit_card',
            '活跃成员判定': 'is_active_member',
            '活跃成员': 'is_active_member',
            '评估薪资': 'estimated_salary',
            '估计薪水': 'estimated_salary',
            '退出': 'exited',
            '流失率': 'exited'
        }
        
        # 重命名列
        df1_renamed = df1.rename(columns=column_mapping)
        df2_renamed = df2.rename(columns=column_mapping)
        
        # 确保必要的列存在
        required_cols = ['customer_id', 'credit_score', 'country', 'gender', 'age', 
                        'tenure', 'balance', 'products_number', 'has_credit_card', 
                        'is_active_member', 'estimated_salary']
        
        # 从两个数据集中各选择10个客户
        sample1 = df1_renamed[required_cols].sample(n=10, random_state=42)
        sample2 = df2_renamed[required_cols].sample(n=10, random_state=42)
        
        # 合并样本
        test_sample = pd.concat([sample1, sample2], ignore_index=True)
        
        print(f"成功生成测试样本，共{len(test_sample)}个客户")
        return test_sample
        
    except Exception as e:
        print(f"数据加载失败: {e}")
        return None

def prepare_test_data_for_main(sample_df):
    """
    准备测试数据，转换为main.py可以处理的格式
    """
    # 重新映射列名为main.py期望的格式
    reverse_mapping = {
        'customer_id': '客户ID',
        'credit_score': '信用分',
        'country': '国家',
        'gender': '性别',
        'age': '年龄',
        'tenure': '任期',
        'balance': '余额',
        'products_number': '银行产品编号',
        'has_credit_card': '信用卡',
        'is_active_member': '活跃成员',
        'estimated_salary': '估计薪水'
    }
    
    test_df = sample_df.rename(columns=reverse_mapping)
    
    # 保存测试数据到临时文件
    test_file_path = 'test_customers_temp.csv'
    test_df.to_csv(test_file_path, index=False, encoding='utf-8-sig')
    
    return test_df, test_file_path

def run_prediction_analysis(test_df):
    """
    使用优化后的算法进行预测分析
    """
    from sklearn.ensemble import RandomForestClassifier
    from sklearn.preprocessing import StandardScaler, OneHotEncoder
    from sklearn.compose import ColumnTransformer
    from sklearn.pipeline import Pipeline
    
    # 加载训练数据
    train_path = r'c:\Users\ten\Desktop\ad-space-available-master\ad-space-available-master\ad-space-available\project\ABC Multistate 银行流失率.csv'
    train_df = pd.read_csv(train_path)
    
    # 特征映射
    feature_mapping = {
        '信用评分': '信用分',
        '地理位置': '国家',
        '产品数量': '银行产品编号',
        '拥有收藏卡判定': '信用卡',
        '活跃成员判定': '活跃成员',
        '评估薪资': '估计薪水'
    }
    
    # 重命名测试数据特征
    test_df = test_df.rename(columns=feature_mapping)
    
    # 选择训练特征和目标变量
    train_features = ['信用分', '国家', '性别', '年龄', '任期', '余额', '银行产品编号', '信用卡', '活跃成员', '估计薪水']
    target = '流失率'
    
    # 确保测试数据只包含训练数据中存在的特征
    available_test_features = [f for f in train_features if f in test_df.columns]
    
    # 优化的客户价值计算（多维度评估）
    def calculate_customer_value(row):
        # 基础价值：余额权重60%，薪资权重30%，产品数量权重10%
        base_value = row['余额'] * 0.6 + row['估计薪水'] * 0.3 + row['银行产品编号'] * 1000 * 0.1
        
        # 调整因子
        adjustment_factor = 1.0
        
        # 信用分调整 (±10%)
        if row['信用分'] > 750:
            adjustment_factor += 0.1
        elif row['信用分'] < 600:
            adjustment_factor -= 0.1
            
        # 活跃状态调整 (±5%)
        if row['活跃成员'] == 1:
            adjustment_factor += 0.05
        else:
            adjustment_factor -= 0.05
            
        # 信用卡持有调整 (+3%)
        if row['信用卡'] == 1:
            adjustment_factor += 0.03
            
        # 任期调整 (长期客户+5%)
        if row['任期'] > 5:
            adjustment_factor += 0.05
            
        return base_value * adjustment_factor
    
    # 计算训练集客户价值
    train_df['客户价值'] = train_df.apply(calculate_customer_value, axis=1)
    
    # 计算测试集客户价值
    test_df['客户价值'] = test_df.apply(calculate_customer_value, axis=1)
    
    # 优化的客户价值分层
    def value_stratification(value):
        if value > 80000:
            return '高价值'
        elif value > 30000:
            return '中价值'
        else:
            return '低价值'
    
    train_df['价值分层'] = train_df['客户价值'].apply(value_stratification)
    test_df['价值分层'] = test_df['客户价值'].apply(value_stratification)
    
    # 定义预处理管道
    numeric_features = ['信用分', '年龄', '任期', '余额', '估计薪水']
    categorical_features = ['国家', '性别']
    
    preprocessor = ColumnTransformer(
        transformers=[
            ('num', StandardScaler(), numeric_features),
            ('cat', OneHotEncoder(drop='first'), categorical_features)
        ])
    
    # 创建模型
    model = Pipeline([
        ('preprocessor', preprocessor),
        ('classifier', RandomForestClassifier(
            n_estimators=100,
            class_weight='balanced',
            min_samples_split=5,
            random_state=42
        ))
    ])
    
    # 训练模型
    X_train = train_df[train_features]
    y_train = train_df[target]
    model.fit(X_train, y_train)
    
    # 在测试集上进行预测
    X_test = test_df[available_test_features]
    test_df['流失概率'] = model.predict_proba(X_test)[:, 1] * 100  # 转换为百分比
    
    # 优化的干预策略生成（基于风险-价值矩阵）
    def generate_strategy(row):
        # 根据优化后的阈值确定风险等级
        if row['流失概率'] > 60:
            risk_level = '高风险'
        elif row['流失概率'] > 30:
            risk_level = '中风险'
        else:
            risk_level = '低风险'
        
        # 基于风险-价值矩阵的干预策略
        strategy_matrix = {
            '高风险-高价值': '专属客户经理一对一服务; 定制化产品方案; 紧急挽留计划',
            '高风险-中价值': '发送个性化挽留邮件; 提供产品升级优惠; 电话回访',
            '高风险-低价值': '自动化营销活动; 提供基础产品优惠; 短信关怀',
            '中风险-高价值': '定期关怀电话; 推荐高端理财产品; VIP服务升级',
            '中风险-中价值': '提供高息定期存款产品; 邀请参加会员互动活动',
            '中风险-低价值': '发送产品推荐短信; 提供小额贷款优惠',
            '低风险-高价值': '维持现有服务质量; 推荐投资理财产品; 定期市场分析',
            '低风险-中价值': '定期发送理财建议; 提供积分奖励活动',
            '低风险-低价值': '基础服务维护; 节日问候和小礼品'
        }
        
        strategy_key = f'{risk_level}-{row["价值分层"]}'
        return strategy_matrix.get(strategy_key, '标准客户服务')
    
    test_df['干预策略'] = test_df.apply(generate_strategy, axis=1)
    
    # 增强的属性针对性建议
    def generate_attribute_strategy(row):
        suggestions = []
        
        # 余额相关建议
        if row['余额'] == 0:
            suggestions.append('紧急关注：零余额客户，建议立即联系了解情况')
        elif row['余额'] < 10000:
            suggestions.append('提供高息定期存款产品，鼓励增加存款')
        elif row['余额'] > 200000:
            suggestions.append('推荐高端理财产品和投资咨询服务')
        
        # 产品数量建议
        if row['银行产品编号'] == 1:
            suggestions.append('推荐附加产品：信用卡、理财产品或保险')
        elif row['银行产品编号'] >= 4:
            suggestions.append('产品整合建议：优化产品组合，提供一站式服务')
        
        # 活跃状态建议
        if row['活跃成员'] == 0:
            suggestions.append('激活策略：邀请参加会员互动活动，提供专属优惠')
        
        # 任期建议
        if row['任期'] < 1:
            suggestions.append('新客户关怀：提供入门指导和新客户专享优惠')
        elif row['任期'] < 2:
            suggestions.append('提供长期合作优惠政策，增强客户粘性')
        elif row['任期'] > 8:
            suggestions.append('忠诚客户奖励：提供长期客户专属权益')
        
        # 信用分建议
        if row['信用分'] < 600:
            suggestions.append('信用提升建议：提供信用管理咨询和改善方案')
        elif row['信用分'] > 800:
            suggestions.append('优质信用奖励：提供低息贷款和高额度信用产品')
        
        # 年龄相关建议
        if row['年龄'] < 30:
            suggestions.append('年轻客户专案：推荐理财入门产品和职业发展贷款')
        elif row['年龄'] > 55:
            suggestions.append('退休规划建议：提供养老理财和保险产品')
        
        # 信用卡建议
        if row['信用卡'] == 0:
            suggestions.append('信用卡推荐：根据消费习惯推荐合适的信用卡产品')
        
        return '; '.join(suggestions) if suggestions else '客户状况良好，维持现有服务水平'
    
    test_df['属性干预建议'] = test_df.apply(generate_attribute_strategy, axis=1)
    
    return test_df

def generate_detailed_report(results_df):
    """
    生成详细的文本预测和干预报告
    """
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    report_filename = f'详细测试预测报告_{timestamp}.txt'
    
    with open(report_filename, 'w', encoding='utf-8') as f:
        f.write("=" * 80 + "\n")
        f.write("客户流失预测与干预策略详细测试报告\n")
        f.write("=" * 80 + "\n")
        f.write(f"生成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
        f.write(f"测试样本数量: {len(results_df)}个客户\n")
        f.write(f"使用算法: 优化的RandomForest + 多维度客户价值评估\n")
        f.write("\n")
        
        # 统计摘要
        f.write("📊 统计摘要\n")
        f.write("-" * 40 + "\n")
        f.write(f"平均流失概率: {results_df['流失概率'].mean():.2f}%\n")
        f.write(f"最高流失概率: {results_df['流失概率'].max():.2f}%\n")
        f.write(f"最低流失概率: {results_df['流失概率'].min():.2f}%\n")
        
        # 风险等级分布
        high_risk = len(results_df[results_df['流失概率'] > 60])
        medium_risk = len(results_df[(results_df['流失概率'] > 30) & (results_df['流失概率'] <= 60)])
        low_risk = len(results_df[results_df['流失概率'] <= 30])
        
        f.write(f"高风险客户: {high_risk}个 ({high_risk/len(results_df)*100:.1f}%)\n")
        f.write(f"中风险客户: {medium_risk}个 ({medium_risk/len(results_df)*100:.1f}%)\n")
        f.write(f"低风险客户: {low_risk}个 ({low_risk/len(results_df)*100:.1f}%)\n")
        
        # 价值分层分布
        value_counts = results_df['价值分层'].value_counts()
        f.write(f"高价值客户: {value_counts.get('高价值', 0)}个\n")
        f.write(f"中价值客户: {value_counts.get('中价值', 0)}个\n")
        f.write(f"低价值客户: {value_counts.get('低价值', 0)}个\n")
        f.write("\n")
        
        # 详细客户分析
        f.write("👥 详细客户分析\n")
        f.write("=" * 80 + "\n")
        
        for idx, row in results_df.iterrows():
            f.write(f"\n客户 {idx+1}: {row['客户ID']}\n")
            f.write("-" * 50 + "\n")
            
            # 基本信息
            f.write("📋 基本信息:\n")
            f.write(f"  年龄: {row['年龄']}岁\n")
            f.write(f"  性别: {row['性别']}\n")
            f.write(f"  国家: {row['国家']}\n")
            f.write(f"  任期: {row['任期']}年\n")
            f.write(f"  信用分: {row['信用分']}\n")
            f.write(f"  账户余额: ¥{row['余额']:,.2f}\n")
            f.write(f"  产品数量: {row['银行产品编号']}个\n")
            f.write(f"  信用卡: {'是' if row['信用卡'] == 1 else '否'}\n")
            f.write(f"  活跃成员: {'是' if row['活跃成员'] == 1 else '否'}\n")
            f.write(f"  估计薪水: ¥{row['估计薪水']:,.2f}\n")
            f.write("\n")
            
            # 预测结果
            f.write("🎯 预测结果:\n")
            f.write(f"  流失概率: {row['流失概率']:.2f}%\n")
            f.write(f"  客户价值: ¥{row['客户价值']:,.2f}\n")
            f.write(f"  价值分层: {row['价值分层']}\n")
            
            # 风险等级
            if row['流失概率'] > 60:
                risk_level = '高风险 ⚠️'
            elif row['流失概率'] > 30:
                risk_level = '中风险 ⚡'
            else:
                risk_level = '低风险 ✅'
            f.write(f"  风险等级: {risk_level}\n")
            f.write("\n")
            
            # 干预策略
            f.write("💡 干预策略:\n")
            f.write(f"  主要策略: {row['干预策略']}\n")
            f.write("\n")
            
            # 属性建议
            f.write("🔧 属性改善建议:\n")
            f.write(f"  {row['属性干预建议']}\n")
            f.write("\n")
            
            # 优先级评估
            if row['流失概率'] > 60 and row['价值分层'] in ['高价值', '中价值']:
                priority = '🔴 极高优先级 - 立即行动'
            elif row['流失概率'] > 60:
                priority = '🟠 高优先级 - 24小时内联系'
            elif row['流失概率'] > 30 and row['价值分层'] == '高价值':
                priority = '🟡 中高优先级 - 一周内跟进'
            elif row['流失概率'] > 30:
                priority = '🟢 中等优先级 - 两周内跟进'
            else:
                priority = '🔵 低优先级 - 常规维护'
            
            f.write(f"⭐ 处理优先级: {priority}\n")
            f.write("\n" + "="*80 + "\n")
        
        # 重点关注客户
        f.write("\n🚨 重点关注客户列表\n")
        f.write("-" * 40 + "\n")
        high_priority = results_df[results_df['流失概率'] > 60].sort_values('流失概率', ascending=False)
        
        if len(high_priority) > 0:
            f.write("以下客户需要立即关注和干预:\n\n")
            for idx, row in high_priority.iterrows():
                f.write(f"🔴 客户ID: {row['客户ID']} | 流失概率: {row['流失概率']:.2f}% | 价值: {row['价值分层']} | 策略: {row['干预策略'].split(';')[0]}\n")
        else:
            f.write("✅ 当前没有高风险客户需要紧急关注\n")
        
        f.write("\n")
        f.write("📞 建议行动计划:\n")
        f.write("-" * 40 + "\n")
        f.write("1. 立即联系所有高风险客户（流失概率>60%）\n")
        f.write("2. 一周内跟进中风险高价值客户\n")
        f.write("3. 两周内实施所有属性改善建议\n")
        f.write("4. 建立定期监控机制，每月重新评估\n")
        f.write("\n")
        f.write(f"报告生成完成时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n")
        f.write("=" * 80 + "\n")
    
    print(f"详细报告已生成: {report_filename}")
    return report_filename

def main():
    """
    主函数
    """
    print("🚀 开始执行客户流失预测测试用例...")
    print("=" * 60)
    
    # 1. 加载和采样数据
    sample_data = load_and_sample_data()
    if sample_data is None:
        print("❌ 数据加载失败，程序退出")
        return
    
    # 2. 准备测试数据
    test_df, temp_file = prepare_test_data_for_main(sample_data)
    print(f"✅ 测试数据准备完成，共{len(test_df)}个客户")
    
    # 3. 运行预测分析
    print("\n🔮 正在进行流失预测分析...")
    results_df = run_prediction_analysis(test_df)
    print("✅ 预测分析完成")
    
    # 4. 生成详细报告
    print("\n📝 正在生成详细报告...")
    report_file = generate_detailed_report(results_df)
    
    # 5. 保存结果数据
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    results_file = f'测试预测结果_{timestamp}.csv'
    output_cols = ['客户ID', '信用分', '年龄', '性别', '国家', '余额', '银行产品编号', 
                   '客户价值', '价值分层', '流失概率', '干预策略', '属性干预建议']
    results_df[output_cols].to_csv(results_file, index=False, encoding='utf-8-sig')
    
    # 6. 清理临时文件
    if os.path.exists(temp_file):
        os.remove(temp_file)
    
    print(f"\n🎉 测试完成！")
    print(f"📊 详细报告: {report_file}")
    print(f"📈 结果数据: {results_file}")
    print(f"\n📋 快速摘要:")
    print(f"   测试客户数量: {len(results_df)}")
    print(f"   平均流失概率: {results_df['流失概率'].mean():.2f}%")
    print(f"   高风险客户: {len(results_df[results_df['流失概率'] > 60])}个")
    print(f"   高价值客户: {len(results_df[results_df['价值分层'] == '高价值'])}个")
    
if __name__ == "__main__":
    main()